home *** CD-ROM | disk | FTP | other *** search
- /*
- File: AEvents.c
-
- Contains: This file contains an assortment of functions to deal with
- the Apple Events needed to set the OS 9 desktop. The majority of
- the functionality below came from MoreAppleEvents, but it was not
- yet carbonized (to my knowledge) when I created this sample, so I could
- not directly link with the library that comes with that example.
- Special thanks to GeoWar for help in this area.
-
- Written by:
-
- Copyright: Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- */
-
- #include "Snapshot.h"
-
- static int gNumMonitors = 0;
-
- OSErr SetDesktopPict(AEDesc* pAEDesc,SInt32 pIndex)
- {
- OSErr anErr = noErr;
- AppleEvent theEvent = {typeNull, nil}; // always init AEDescs
- ProcessSerialNumber tPSN;
-
- gNumMonitors = 0; // zero monitor count
- {
- GDHandle tGDHandle = DMGetFirstScreenDevice(true);
- while (tGDHandle)
- {
- gNumMonitors++; // bump count
- tGDHandle = DMGetNextScreenDevice(tGDHandle,true);
- }
- }
- if (gNumMonitors == 0)
- gNumMonitors = 1;
-
- // Launch reciever if it's not already running.
- anErr = LaunchProcessBySignature('APPC', 'apcp',&tPSN);
- if (anErr != noErr)
- return anErr;
-
- //moreisbetter or AEHelpers
- anErr = AEHMakeEventSignatureTarget('APPC', 'apcp', kAECoreSuite, kAESetData, &theEvent);
- if (anErr == noErr) // if it worked
- {
- AEDesc containerObj = {typeNull, nil}; // always init AEDescs
- AEDesc propertyObject = {typeNull, nil}; // always init AEDescs
-
- anErr = MakePictureProperty(pIndex,&containerObj, &propertyObject);
- if (anErr == noErr) // if it worked
- {
- anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject);
- AEDisposeDesc(&propertyObject); // Always dispose ASAP
-
- if (anErr == noErr) // if it worked
- {
- AEDesc tAEObject = {typeNull, nil}; // always init AEDescs
-
- anErr = AECoerceDesc(pAEDesc,typeAlias,&tAEObject); // coerce pAEDesc to type alias
- if (anErr == noErr) // if it worked
- {
- anErr = AEPutParamDesc(&theEvent, keyAEData, &tAEObject);
- AEDisposeDesc(&tAEObject); // Always dispose ASAP
- if (anErr == noErr) // if it worked
- {
- anErr = AEHSendEventNoReturnValue(nil, &theEvent);
- }
- }
- }
- }
- AEDisposeDesc(&theEvent); // Always dispose ASAP
- }
- if (anErr != noErr)
- DebugStr("\p|Set_DesktopPict-I-Error;error r30;");
- return anErr;
- }
-
- static OSErr MakePictureProperty(SInt32 pIndex,
- AEDesc* containerObjPtr,
- AEDesc* propertyObjPtr)
- {
- AEDesc longAEDesc = {typeNull, nil}; // always init AEDescs
- SInt32 index = ((pIndex - 1) % gNumMonitors) + 1;
- OSErr anErr = AECreateDesc(typeSInt32, &index, sizeof(long), &longAEDesc);
-
- if (anErr == noErr) // if it worked
- {
- AEDesc cmonAEDesc = {typeNull, nil}; // always init AEDescs
-
- // 'cmon' is nth (pIndex) color monitor object
- anErr = CreateObjSpecifier('cmon',containerObjPtr,formAbsolutePosition,&longAEDesc,false,&cmonAEDesc);
- AEDisposeDesc(&longAEDesc); // Always dispose ASAP
-
- if (anErr == noErr) // if it worked
- {
- AEDesc dpicDesc = {typeNull, nil}; // always init AEDescs
- OSType dpicOSType = 'dpic'; // Desktop Picture
-
- anErr = AECreateDesc('type', &dpicOSType, sizeof(OSType), &dpicDesc);
- if (anErr == noErr) // if it worked
- {
- anErr = CreateObjSpecifier(typeProperty,&cmonAEDesc,formPropertyID,&dpicDesc,false,propertyObjPtr);
- AEDisposeDesc(&cmonAEDesc); // Always dispose ASAP
- }
- }
- }
- return anErr;
- }
-
- pascal OSErr OHMakeAliasDescFromFSSpec( const FSSpecPtr fssPtr,
- AEDesc *aliasDescPtr )
- {
- OSErr anErr = noErr;
- AliasHandle aliasHandle;
-
- anErr = NewAlias( nil, fssPtr, &aliasHandle);
- if ( anErr == noErr && aliasHandle == nil )
- {
- anErr = paramErr;
- }
-
- if ( anErr == noErr )
- {
- anErr = OHMakeAliasDesc( aliasHandle, aliasDescPtr );
- DisposeHandle( (Handle)aliasHandle );
- }
-
- return anErr;
- }//end MakeAliasObject
-
- pascal OSErr OHMakeAliasDesc( const AliasHandle aliasHandle,
- AEDesc *aliasDescPtr )
- {
- OSErr anErr = noErr;
-
- char handleState = HGetState( (Handle)aliasHandle );
- HLock( (Handle)aliasHandle );
-
- anErr = AECreateDesc( typeAlias, *aliasHandle, GetHandleSize( (Handle)aliasHandle ), aliasDescPtr );
-
- HSetState( (Handle)aliasHandle, handleState );
-
- return anErr;
- }//end MakeAliasObject
-
- pascal OSErr AEHMakeEventSignatureTarget( const OSType targetType,
- const OSType targetCreator,
- const AEEventClass eventClass,
- const AEEventID eventID,
- AppleEvent *theEventPtr )
- {
- OSErr anErr = noErr;
-
- ProcessSerialNumber psn = { kNoProcess, kNoProcess };
-
- anErr = FindProcessBySignature( targetType, targetCreator, &psn );
- if ( anErr == noErr )
- {
- anErr = AEHMakeEventProcessTarget( &psn, eventClass, eventID, theEventPtr );
- }
- return anErr;
- }//end AEHMakeEventSignatureTarget
-
- pascal OSErr AEHMakeEventProcessTarget( const ProcessSerialNumberPtr psnPtr,
- const AEEventClass eventClass,
- const AEEventID eventID,
- AppleEvent *theEventPtr )
- {
- OSErr anErr = noErr;
- AEDesc targetAppDesc = { typeNull, nil };
-
- anErr = AECreateDesc (typeProcessSerialNumber, psnPtr, sizeof( ProcessSerialNumber ), &targetAppDesc);
-
- if ( anErr == noErr )
- {
- anErr = AECreateAppleEvent( eventClass, eventID, &targetAppDesc,
- kAutoGenerateReturnID, kAnyTransactionID, theEventPtr);
- }
-
- AEDisposeDesc( &targetAppDesc );
-
- return anErr;
- }//end AEHMakeEventProcessTarget
-
- pascal OSErr AEHSendEventNoReturnValue( const AEIdleUPP idleProcUPP,
- const AppleEvent *theEvent )
- {
- OSErr anErr = noErr;
- AppleEvent theReply = { typeNull, nil };
- AESendMode sendMode;
-
- if ( idleProcUPP == nil )
- sendMode = kAENoReply;
- else
- sendMode = kAEWaitReply;
-
- anErr = AESend( theEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, idleProcUPP, nil );
- if ( anErr == noErr && sendMode == kAEWaitReply )
- {
- anErr = AEHGetHandlerError( &theReply );
- }
- (void) AEDisposeDesc( &theReply );
-
- return anErr;
- }//end AEHSendEventNoReturnValue
-
- pascal OSErr AEHGetHandlerError( const AppleEvent *reply )
- {
- OSErr anErr = noErr;
- OSErr handlerErr;
-
- DescType actualType;
- long actualSize;
-
- if ( reply->descriptorType != typeNull ) // there's a reply, so there may be an error
- {
- OSErr getErrErr = noErr;
-
- getErrErr = AEGetParamPtr( reply, keyErrorNumber, typeShortInteger, &actualType,
- &handlerErr, sizeof( OSErr ), &actualSize );
-
- if ( getErrErr != errAEDescNotFound ) // found an errorNumber parameter
- {
- anErr = handlerErr; // so return it's value
- }
- }
- return anErr;
- }//end AEHGetHandlerError
-
- pascal OSErr FindProcessBySignature( const OSType targetType,
- const OSType targetCreator,
- ProcessSerialNumberPtr psnPtr )
- {
- OSErr anErr = noErr;
- Boolean lookingForProcess = true;
-
- ProcessInfoRec infoRec;
-
- infoRec.processInfoLength = sizeof( ProcessInfoRec );
- infoRec.processName = nil;
- infoRec.processAppSpec = nil;
-
- psnPtr->lowLongOfPSN = kNoProcess;
- psnPtr->highLongOfPSN = kNoProcess;
-
- while ( lookingForProcess )
- {
- anErr = GetNextProcess( psnPtr );
- if ( anErr != noErr )
- {
- lookingForProcess = false;
- }
- else
- {
- anErr = GetProcessInformation( psnPtr, &infoRec );
- if ( ( anErr == noErr )
- && ( infoRec.processType == targetType )
- && ( infoRec.processSignature == targetCreator ) )
- {
- lookingForProcess = false;
- }
- }
- }
-
- return anErr;
- }//end FindProcessBySignature
-
- OSErr LaunchProcessBySignature(
- const OSType pTargetType,const OSType pTargetCreator,ProcessSerialNumberPtr psnPtr)
- {
- FSSpec appFSSpec;
- OSErr anErr = FindProcessBySignature(pTargetType, pTargetCreator, psnPtr);
-
- if (anErr == noErr) // already running
- return anErr;
-
- // It's not already running, so look for it (as an APPL) in the desktop database
- if (pTargetType == 'APPL')
- anErr = Find_DTDB_APPL(pTargetCreator,&appFSSpec);
-
- // If we haven't found it yet, search all the volumes
- if (anErr != noErr)
- anErr = Search_Volumes(pTargetType,pTargetCreator,&appFSSpec);
-
- // we found it, so try to launch it
- if (anErr == noErr)
- {
- LaunchParamBlockRec tLaunchPB;
-
- tLaunchPB.launchBlockID = extendedBlock;
- tLaunchPB.launchEPBLength = extendedBlockLen;
- tLaunchPB.launchFileFlags = nil;
- tLaunchPB.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- tLaunchPB.launchAppSpec = &appFSSpec;
-
- anErr = LaunchApplication(&tLaunchPB);
- if (anErr == noErr)
- *psnPtr = tLaunchPB.launchProcessSN;
- }
- return anErr;
- }
-
- static OSErr Search_Volumes(const OSType pTargetType,const OSType pTargetCreator,FSSpec* pFSSpecPtr)
- {
- SInt16 index;
- OSErr anErr = noErr;
-
- for (index = 1;;index++) // for each volume...
- {
- XVolumeParam tXVPV;
-
- tXVPV.ioCompletion = nil;
- tXVPV.ioNamePtr = nil;
- tXVPV.ioVolIndex = index;
-
- anErr = PBXGetVolInfoSync(&tXVPV); // get its ioVRefNum
- if (anErr == nsvErr) // if no such volume...
- anErr = afpItemNotFound; // ...return application information not found
- if (anErr != noErr) // on error...
- break; // ...break
-
- anErr = Search_Volume(tXVPV.ioVRefNum,pTargetType,pTargetCreator,pFSSpecPtr);
- if (anErr == noErr) // if we found it...
- break; // ...break
- }
- return anErr;
- }
-
- static OSErr Search_Volume(const SInt16 pVRefNum,const OSType pTargetType,const OSType pTargetCreator,FSSpec* pFSSpecPtr)
- {
- CSParamPtr tCSParamPtr;
- OSErr anErr;
-
- if (!pFSSpecPtr)
- return paramErr;
-
- tCSParamPtr = (CSParamPtr) NewPtrClear(sizeof(CSParam));
- if (tCSParamPtr == nil)
- return MemError();
-
- // initialize the parameter block
- tCSParamPtr->ioVRefNum = pVRefNum;
- tCSParamPtr->ioMatchPtr = pFSSpecPtr;
- tCSParamPtr->ioSearchBits = fsSBFlFndrInfo;
-
- tCSParamPtr->ioReqMatchCount = 1; // only looking for 1
- tCSParamPtr->ioSearchTime = 0; // no timeout
-
- tCSParamPtr->ioSearchInfo1 = (CInfoPBPtr) NewPtrClear(sizeof(CInfoPBRec));
- tCSParamPtr->ioSearchInfo2 = (CInfoPBPtr) NewPtrClear(sizeof(CInfoPBRec));
-
- if (tCSParamPtr->ioSearchInfo1 && tCSParamPtr->ioSearchInfo2)
- {
- // Now see if we can create an 2K optimization buffer
- tCSParamPtr->ioOptBuffer = NewPtr(2048);
- if (tCSParamPtr->ioOptBuffer)
- tCSParamPtr->ioOptBufSize = 2048;
- else
- tCSParamPtr->ioOptBufSize = 0; // no buffer, sorry
-
- tCSParamPtr->ioSearchInfo1->hFileInfo.ioNamePtr = nil;
- tCSParamPtr->ioSearchInfo2->hFileInfo.ioNamePtr = nil;
- tCSParamPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = pTargetType;
- tCSParamPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator = pTargetCreator;
-
- tCSParamPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF;
- tCSParamPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
-
- anErr = PBCatSearchSync(tCSParamPtr); // search sync
- // if ((anErr != noErr) || (tCSParamPtr->ioActMatchCount == 0))
- }
- else
- anErr = MemError();
-
- // no matter what happened, kill all the memory we allocated
- if (tCSParamPtr->ioSearchInfo1)
- DisposePtr((Ptr)tCSParamPtr->ioSearchInfo1);
-
- if (tCSParamPtr->ioSearchInfo2)
- DisposePtr((Ptr)tCSParamPtr->ioSearchInfo2);
-
- if (tCSParamPtr->ioOptBuffer)
- DisposePtr((Ptr)tCSParamPtr->ioOptBuffer);
-
- DisposePtr((Ptr)tCSParamPtr);
-
- return(anErr);
- }
-
- static OSErr Find_DTDB_APPL(const OSType pTargetCreator,FSSpec* pFSSpecPtr)
- {
- SInt16 index;
- OSErr anErr = noErr;
-
- for (index = 1;;index++) // for each volume...
- {
- XVolumeParam tXVPV;
- DTPBRec deskTopDBRec;
-
- tXVPV.ioCompletion = nil;
- tXVPV.ioNamePtr = nil;
- tXVPV.ioVolIndex = index;
-
- anErr = PBXGetVolInfoSync(&tXVPV); // get its ioVRefNum
- if (anErr == nsvErr) // if no such volume...
- anErr = afpItemNotFound; // ...return application information not found
- if (anErr != noErr) // on error...
- break; // ...break
-
- // now get the DTDB for this volume
- deskTopDBRec.ioNamePtr = nil;
- deskTopDBRec.ioVRefNum = tXVPV.ioVRefNum;
- anErr = PBDTGetPath( &deskTopDBRec );
- if (anErr != noErr)
- break;
-
- // look in this DTDB for the app with this creator
- deskTopDBRec.ioCompletion = nil;
- deskTopDBRec.ioNamePtr = pFSSpecPtr->name;
- deskTopDBRec.ioIndex = 0;
- deskTopDBRec.ioFileCreator = pTargetCreator;
-
- anErr = PBDTGetAPPLSync( &deskTopDBRec );
- if (anErr == noErr) // found it
- { // stuff our FSSpec
- pFSSpecPtr->vRefNum = deskTopDBRec.ioVRefNum;
- pFSSpecPtr->parID = deskTopDBRec.ioAPPLParID;
- break;
- }
- }
- return anErr;
- }
-